package com.hunter.common.util.document;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

public class XwpfUtil {

	public static void main(String[] args) {
		 Map<String, String> params = new HashMap<String, String>();
		 params.put("hao", "2014-02-28");
		 params.put("appleAmt", "100.00");
		 params.put("bananaAmt", "200.00");
		 params.put("totalAmt", "300.00");
		Matcher matcher;
		String runText = "${hao}deaaassd${appleAmt}gasdgasdg";
//			while ((matcher = matcher(runText)).find()) {
//				runText = matcher.replaceFirst(params.get(matcher.group(1))==null?"ERROR":params.get(matcher.group(1)));
//				System.out.println(runText);
//			}
		
		matcher = matcher(runText);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
	       matcher.appendReplacement(sb, params.get(matcher.group(1))==null?"ERROR":params.get(matcher.group(1)));
	    }
	    matcher.appendTail(sb);	
		System.out.println(sb);
	}

	/**
	 * // * 用一个docx文档作为模板，然后替换其中的内容，再写入目标文档中。 // * @throws Exception //
	 */

	public static void replaceInPara(Map<String, String> params, String sourcePath, String targetPath) {
		try {
			InputStream is = new FileInputStream(sourcePath);
			XWPFDocument doc = new XWPFDocument(is);
			// 替换段落里面的变量
			replaceInPara(doc, params);
			// 替换表格里面的变量
			replaceInTable(doc, params);
			OutputStream os = new FileOutputStream(targetPath);
			doc.write(os);
			close(os);
			close(is);
			doc.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 替换段落里面的变量
	 * 
	 * @param doc
	 *            要替换的文档
	 * @param params
	 *            参数
	 */
	private static void replaceInPara(XWPFDocument doc, Map<String, String> params) {
		Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
		XWPFParagraph para;
		while (iterator.hasNext()) {
			para = iterator.next();
			replaceInPara(para, params);
		}
	}

	/**
	 * 替换段落里面的变量
	 * 
	 * @param para
	 *            要替换的段落
	 * @param params
	 *            参数
	 */
	private static void replaceInPara(XWPFParagraph para, Map<String, String> params) {
		List<XWPFRun> runs;
		Matcher matcher;

		String runText = "";
		if (matcher(para.getParagraphText()).find()) {
			runs = para.getRuns();
			if (runs.size() > 0) {
				int j = runs.size();
				for (int i = 0; i < j; i++) {
					XWPFRun run = runs.get(0);
					String i1 = run.toString();
					runText += i1;
					para.removeRun(0);
				}
			}
//			matcher = matcher(runText);

//			if (matcher.find()) {
				while ((matcher = matcher(runText)).find()) {
					runText = matcher.replaceFirst(params.get(matcher.group(1))==null?"ERROR":params.get(matcher.group(1)));
				}
				// 直接调用XWPFRun的setText()方法设置文本时，在底层会重新创建一个XWPFRun，把文本附加在当前文本后面，
				// 所以我们不能直接设值，需要先删除当前run,然后再自己手动插入一个新的run。

				para.insertNewRun(0).setText(runText);
//			}
		}
	}
	/**
	 * 替换表格里面的变量
	 * 
	 * @param doc
	 *            要替换的文档
	 * @param params
	 *            参数
	 */
	private static void replaceInTable(XWPFDocument doc,
			Map<String, String> params) {
		Iterator<XWPFTable> iterator = doc.getTablesIterator();
		XWPFTable table;
		List<XWPFTableRow> rows;
		List<XWPFTableCell> cells;
		List<XWPFParagraph> paras;
		while (iterator.hasNext()) {
			table = iterator.next();
			rows = table.getRows();
			for (XWPFTableRow row : rows) {
				cells = row.getTableCells();
				for (XWPFTableCell cell : cells) {
					paras = cell.getParagraphs();
					for (XWPFParagraph para : paras) {
						replaceInPara(para, params);
					}
				}
			}
		}
	}

	/**
	 * 正则匹配字符串
	 * 
	 * @param str
	 * @return
	 */
	private static Matcher matcher(String str) {
		Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(str);
		return matcher;
	}

	/**
	 * 关闭输入流
	 * 
	 * @param is
	 */
	private static void close(InputStream is) {
		if (is != null) {
			try {
				is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 关闭输出流
	 * 
	 * @param os
	 */
	private static void close(OutputStream os) {
		if (os != null) {
			try {
				os.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private static void replacePicture(String blipId, int id, int width, int height,
			XWPFRun run) {
		final int EMU = 9525;
		width *= EMU;
		height *= EMU;
		// String blipId =
		// getAllPictures().get(id).getPackageRelationship().getId();
//		if (paragraph == null) {
//			paragraph = createParagraph();
//		}
		CTInline inline = run.getCTR().addNewDrawing()
				.addNewInline();
		String picXml = ""
				+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
				+ "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
				+ "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
				+ "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""
				+ id
				+ "\" name=\"img_"
				+ id
				+ "\"/>"
				+ "            <pic:cNvPicPr/>"
				+ "         </pic:nvPicPr>"
				+ "         <pic:blipFill>"
				+ "            <a:blip r:embed=\""
				+ blipId
				+ "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
				+ "            <a:stretch>"
				+ "               <a:fillRect/>"
				+ "            </a:stretch>"
				+ "         </pic:blipFill>"
				+ "         <pic:spPr>"
				+ "            <a:xfrm>"
				+ "               <a:off x=\"0\" y=\"0\"/>"
				+ "               <a:ext cx=\""
				+ width
				+ "\" cy=\""
				+ height
				+ "\"/>"
				+ "            </a:xfrm>"
				+ "            <a:prstGeom prst=\"rect\">"
				+ "               <a:avLst/>"
				+ "            </a:prstGeom>"
				+ "         </pic:spPr>"
				+ "      </pic:pic>"
				+ "   </a:graphicData>" + "</a:graphic>";
		// CTGraphicalObjectData graphicData =
		// inline.addNewGraphic().addNewGraphicData();
		XmlToken xmlToken = null;
		try {
			xmlToken = XmlToken.Factory.parse(picXml);
		} catch (XmlException xe) {
			xe.printStackTrace();
		}
		inline.set(xmlToken);
		// graphicData.set(xmlToken);
		inline.setDistT(0);
		inline.setDistB(0);
		inline.setDistL(0);
		inline.setDistR(0);
		CTPositiveSize2D extent = inline.addNewExtent();
		extent.setCx(width);
		extent.setCy(height);
		CTNonVisualDrawingProps docPr = inline.addNewDocPr();
		docPr.setId(id);
		docPr.setName("docx_img_ " + id);
		docPr.setDescr("docx Picture");
	}

}